package com.ly.mpayment.rest.up.meijia;

import com.alibaba.fastjson.JSONObject;
import com.ly.mpayment.core.secuity.MD5;
import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.UpOrder;
import com.ly.mpayment.persist.entity.UpShopInfo;
import com.ly.mpayment.persist.service.downrechargeflow.IDownRechargeFlowService;
import com.ly.mpayment.persist.service.downshopinfo.IDownShopInfoService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import com.ly.mpayment.persist.service.upshopinfo.IUpShopInfoService;
import com.ly.mpayment.rest.recharge.RechargeRest;
import org.apache.log4j.Logger;
import org.mortbay.util.MultiMap;
import org.mortbay.util.UrlEncoded;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

@Component
@Path("meijia")
public class MeiJiaRest {

	Logger logger = Logger.getLogger(MeiJiaRest.class);


	@Autowired
	IUporderService upOrderService;

	@Autowired
	IDownRechargeFlowService flowService;

	@Autowired
	IDownShopInfoService shopService;

	@Autowired
	IUpShopInfoService upShopInfoService;

	/**
	 * @return
	 */
	@Path("callBack")
	@POST
	public synchronized String callBack(@RequestBody String body){
		logger.info("meijia:"+body);
		MultiMap multimap = parceString(body);
		if(!StringUtils.isBlank(body)){
			UpOrder order = upOrderService.findById(multimap.getString("outOrderId"));
			if (order != null && multimap.getString("orderStatus").equals("2") && order.getStatus() == Config.status[0]) {
				order.setRemark(multimap.containsKey("ext1") ? multimap.getString("ext1") : multimap.getString("orderDesc"));
				RechargeRest.successUpOrder.add(order);
				return "ok";
			}else if(order != null && order.getStatus() == Config.status[0] && multimap.getString("orderStatus").equals("3")){
				order.setRemark(multimap.containsKey("orderDesc") ? multimap.getString("orderDesc") :  multimap.getString("orderDesc"));
				RechargeRest.failtUpOrder.add(order);
				return "ok";
			}else{
				logger.info("meijia_not_found_order:" + body +","+ (order == null ? " order is null" : order.getUpphonenum() ));
			}
		}
		return "failt";
	}

	private MultiMap parceString(String str){
		MultiMap map = new MultiMap();
		UrlEncoded.decodeTo(str, map, "utf-8");
		return map;
	}

	/**
	 * 签名
	 * @param jsonObject
	 * @param key
	 * @return
	 */
	private String sign(JSONObject jsonObject, String key,String keyValue){
		//将所有请求的参数放进TreeMap，TreeMap默认按照key升序排列
		Map<String, String> map = new TreeMap<>();
		for(String s : jsonObject.keySet()){
			map.put(s,jsonObject.getString(s));
		}

		StringBuilder sb = new StringBuilder();
		//循环拼接所有value
		for (String k : map.keySet()) {
			sb.append(k);
			sb.append("=");
			sb.append(map.get(k));
			sb.append("&");
		}
		//最后拼接上秘钥
		sb.append(key);
		sb.append("=");
		sb.append(keyValue);
		logger.info("签名前：" + sb.toString());
		return MD5.md5(sb.toString());
	}

	/**
	 * 字段名称	字段说明	类型	必填	备注
	 * agentAcct	账号	string(30)	Y	需申请开通
	 * orderId	订单编号	string(30)	Y	需保障唯一性
	 * bizType	业务类型	string(30)	Y	详见业务编码列表
	 * phoneNum	充值号码	string(11)	Y	11位手机号码。(当phoneType为固话或宽带充值时，充值号码前面必须加上区号，最大限制15位)
	 * phoneType	号码类型	string(10)	N	详见“号码类型编码列表”；不填默认以本平台为准
	 * amount	充值金额	int(10)	Y	单位:元
	 * timestamp	请求时间戳	long(13)	Y	单位:毫秒
	 * sign	签名	string(32)	Y	MD5加密，详见签名规则
	 *
	 * 字段名称	字段说明	类型	必填	备注
	 * agentAcct	账号	string(30)	Y	-
	 * orderId	订单编号	string(30)	Y	-
	 * retCode	响应编码	string(30)	Y	详见响应编码列表
	 * retMsg	响应描述	string(50)	Y	不参与签名
	 * sign	签名	string(32)	Y	MD5加密，详见签名规则
	 * @return
	 */
	public void commitOrder(UpOrder order, UpShopInfo shop) {
		UpOrder product = this.upOrderService.findOrderProduct(order.getUporderuuid());
		if (product != null) {
			JSONObject data = new JSONObject();
			data.put("appId",shop.getAppId());
			data.put("outOrderId",order.getUporderuuid());
			data.put("itemId",product.getUpShopPro().getProductCode());
			data.put("uuid",order.getUpphonenum());
			data.put("itemFace",product.getUpShopPro().getUpfacevalue());
			data.put("amount",order.getUprechargenum());
			data.put("timestamp", new DateUtils().toTimeStamps());
			data.put("appSecret",shop.getUpkey());
			data.put("sign",MD5.md5(StringSort.doSign(data)));
			data.remove("appSecret");
			String res = HttpClient.postUrl(shop.getOrderCommitAddress(),StringSort.jsonToString(data));
			logger.info("commitmeijia_result:" + data +",phone:"+order.getUpphonenum()+",res:"+res);
			if (!StringUtils.isBlank(res)) {
				JSONObject result = JSONObject.parseObject(res);
				if(result.containsKey("code") && result.getString("code").equals("00")){
					upOrderService.updateUpOrderMsg(order, result.getString("orderId"),result.getString("msg"));
				}else if (result.containsKey("code") && codesError.contains(result.getString("code"))) {
					order.setRemark(result.containsKey("msg") ?	result.getString("msg") : Config.orderFailA);
					RechargeRest.failtUpOrder.add(order);
				}
			} else {
				upOrderService.commitFailt(order,  Config.commitFailt);
				logger.info("commitmeijia_error" + order.getUpphonenum());
			}
		}
	}

	/**
	 * 提单错误直接失败
	 */
	private static Set<String> codesError = new HashSet<String>(){{
		add("-10");
		add("-12");
		add("-13");
		add("-14");
		add("-15");
		add("-16");
		add("-18");
		add("-21");
	}};

	/**
	 * @return
	 */
	public void queryOrder(UpOrder upOrder, UpShopInfo shopInfo) {
		if(upOrder != null ){
			UpOrder product = upOrderService.findOrderProduct(upOrder.getUporderuuid());
			if (product != null) {
				JSONObject data = new JSONObject();
				data.put("appId",shopInfo.getAppId());
				data.put("outOrderId",upOrder.getUporderuuid());
				data.put("timestamp",new DateUtils().toTimeStamps());
				data.put("appSecret",shopInfo.getUpkey());
				data.put("sign",MD5.md5(StringSort.doSign(data)));
				data.remove("appSecret");
				String res = HttpClient.postUrl(shopInfo.getOrderStatusAddress(),StringSort.jsonToString(data));
				logger.info("querymeijia:"+res+"data:"+data+",phone:"+upOrder.getUpphonenum());
				if(res != null){
					JSONObject result = JSONObject.parseObject(res);
					if(result.containsKey("code") && result.getString("code").equals("00")){
						if(result.getString("orderStatus").equals("2") ){
							UpOrder order = upOrderService.findById(upOrder.getUporderuuid());
							if(order != null && order != null && order.getStatus() == Config.status[0]){
								order.setRemark(result.containsKey("ext1") ? result.getString("ext1") : result.getString("status"));
								RechargeRest.successUpOrder.add(order);
							}
						}else if( result.getString("orderStatus").equals("3") ){
							UpOrder order = upOrderService.findById(upOrder.getUporderuuid());
							if( order != null && order.getStatus() == Config.status[0]){
								order.setRemark(result.containsKey("orderDesc") ?	result.getString("orderDesc") : Config.orderFailA);
								RechargeRest.failtUpOrder.add(order);
							}
						}else if(result.getString("orderStatus").equals("4")){
							UpOrder order = upOrderService.findById(upOrder.getUporderuuid());
							upOrderService.addOrderMsg(order,  	result.getString("orderDesc"));
						}
					}else{
						logger.debug("querymeijia查询失败:"+upOrder.getUpphonenum());
					}
				}else{
					logger.info("querymeijia order failt:"+upOrder.getUpphonenum());
				}
			}
		}else{
			logger.info("querymeijia order failt:"+upOrder.getUpphonenum());
		}
	}
}
